iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 15
0
AI & Machine Learning

機器學習你也可以 - 文組帶你手把手實做機器學習聖經系列 第 15

線性模型 - 動手做做看 Logistic Regression篇

  • 分享至 

  • xImage
  •  

上一篇我們提到了二元分類的logistic regression,今天來看一下多類別的實做方式。

補充一下昨天沒有寫清楚的部份

這邊的Yn是,第n筆資料是第一個類別的機率,因為是二元分類,所以(1 - Yn)就是第二個類別的機率。

那多元分類有幾個跟二元稍微不同的地方,首先二元分類的Yn是以sigmoid function,而在多元分類中,會以softmax來表示,寫成

意思就是第n筆資料是第k個類別的機率是多少,其中

知道這個之後就可以簡單的寫下likelihood

並且得到error function

而昨天提到的牛頓法,我們需要的就是這個error function的一次與二次微分

接著我們就可以利用這兩個式子來寫程式囉!我用的資料集在這

import numpy as np
from numpy.linalg import inv
import matplotlib.pyplot as plt
from math import isnan

data =  np.loadtxt(open('train.csv' , 'r'), delimiter = ',')
target = data[:,0:3]
feature = data[:,3:]

def phi(x):
        x = np.reshape(x,(len(x),1))
        return x
        
def y(n,k,w,X): #softmax
        s = np.float64(0.)
	ak = w[k].T.dot(phi(X[n]))
        for j in range(3):
                aj = w[j].T.dot(phi(X[n]))
                s += np.nan_to_num(np.exp(aj - ak))
        s = np.nan_to_num(s)
        return 1./s
        
def gradient(w,k,t,X):
	output = np.zeros((len(w[0]),1))
	for n in range(len(X)):
		scale = y(n,k,w,X) - t[:,k][n] #Ynk - Tnk
		output += scale * phi(X[n])
	return output
    
def hessian(w,k,X):
	output = np.zeros((len(w[0]),len(w[0])))
	for n in range(len(X)): 
		scale = y(n,k,w,X) * (1 - y(n,k,w,X))
		output += scale * (phi(X[n]).dot(phi(X[n]).T)) 
	return output
    
def error(w,t,X):
	s = np.float64(0.)
	for n in range(len(X)):
		for k in range(3):
			if t[:,k][n] != 0.:
				s += np.nan_to_num(np.log(y(n,k,w,X)))
	return -1*s
    
def classify(w,x):
	softmax = []
	for k in range(3):
		s = np.float64(0.)
		ak = w[k].T.dot(phi(x))
		for j in range(3):
			aj = w[j].T.dot(phi(x))
			s += np.nan_to_num(np.exp(aj - ak))
		softmax += [1./s]
	return softmax.index(max(softmax))

w = np.zeros((3,len(phi(feature[0])),1))
cee = []
acc = []
while True:
	e = error(w,target, feature)
	acc += [accuracy(w,target,feature)]
	cee += [np.reshape(e,1)]
	if e < 0.001:
		break
	for k in range(3):
		w[k] = w[k] - inv(hessian(w,k,feature)).dot(gradient(w,k,target,feature))

epoch = [i for i in range(len(cee))]
plt.xlabel('epoch')
plt.ylabel('cross entropy error')
plt.plot(epoch, cee, linestyle = '-')
plt.xticks(epoch)
plt.savefig('cross_entropy_error.png')

結果大概會得到這樣的圖,確定cross entropy error的確有在下降,也證明這個演算法是有用的!


上一篇
線性模型 - 分類(2) 邏輯回歸 Logistic Regression
下一篇
Kernel method - 前言
系列文
機器學習你也可以 - 文組帶你手把手實做機器學習聖經30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言